import { getAppSettingFormItems, getAppSettingFormItemValue, getAppSettingItems, saveAppSetting } from '@/apis/app-manage'
import { Button, Drawer, Form, FormItem, Input, InputNumber, message, Select, Space, Spin, Switch, Textarea } from 'ant-design-vue'

const ComponentMap = {
  AioInput: Input,
  AioInputNumber: InputNumber,
  AioSelect: Select,
  AioSwitch: Switch,
  AioTextarea: Textarea,
}

export default defineComponent({
  emits: ['success'],
  setup(_, { expose, emit }) {
    const open = ref(false)
    const loading = ref(false)
    const submitLoading = ref(false)

    const formSettingItems = ref<any[]>([])
    const formItems = ref<any[]>([])

    const formState = reactive<any>({})
    const rules = {}

    async function initSettingItems() {
      formItems.value.length = 0
      const res = await getAppSettingItems()
      formSettingItems.value = res.data
      if (res.status === 0) {
        const formItemsRes = await Promise.all(formSettingItems.value.map((it: any) => getAppSettingFormItems(it.key)))
        formItemsRes.forEach((it: any, index: number) => {
          formSettingItems.value[index].elementKeys = it.data.elements.map((item: any) => item.key)
        })
        formItems.value = formItemsRes.map((it: any) => it.data)
        formItems.value.forEach((it: any) => {
          it.elements.forEach((ele: any) => {
            (formState as any)[ele.key] = ele.defaultValue
          })
        })
      }
    }

    onMounted(initSettingItems)

    function renderFormItems(item: any) {
      const Component = (ComponentMap as any)[item.type] || Input
      if (Component === Switch) {
        return (
          <Component
            checked={formState[item.key]}
            onUpdate:checked={(value: any) => (formState[item.key] = value)}
            placeholder={item.placeholder || item.label}
            {...item.properties}
          >
          </Component>
        )
      }
      return (
        <Component
          value={formState[item.key]}
          onUpdate:value={(value: any) => (formState[item.key] = value)}
          placeholder={item.placeholder || item.label}
          {...item.properties}
        >
        </Component>
      )
    }
    async function onSubmit() {
      try {
        const submitItems = Object.keys(formState).filter(it => it !== 'appId' && formState[it] !== null)
        if (submitItems.length === 0) {
          message.error('请至少填写一项要保存的配置')
        }
        else {
          submitLoading.value = true
          const res = await Promise.all(formSettingItems.value.map(it =>
            saveAppSetting({ appId: formState.appId, settingKey: it.key, settingValue: it.elementKeys.reduce((pre: any, ele: string) => {
              pre[ele] = formState[ele]
              return pre
            }, {}) })))
          if (res.every(it => it.status === 0)) {
            message.success('保存成功')
            open.value = false
            emit('success')
          }
          else {
            message.error('保存失败')
          }
        }
      }
      finally {
        submitLoading.value = false
      }
    }
    expose({
      async open(row: any) {
        open.value = true
        Object.keys(formState).forEach((key) => {
          formState[key] = typeof formState[key] === 'boolean' ? false : ''
        })
        formState.appId = row.appId
        try {
          loading.value = true
          if (formItems.value.length === 0) {
            await initSettingItems()
          }
          const res = await Promise.all(formSettingItems.value.map((it: any) => getAppSettingFormItemValue(row.appId, it.key)))
          res.forEach((it) => {
            Object.keys(it.data).forEach((key) => {
              if (key in formState) {
                formState[key] = it.data[key]
              }
            })
          })
        }
        finally {
          loading.value = false
        }
      },
    })

    return () => (
      <Drawer open={open.value} width="40%" title="应用配置" onClose={() => (open.value = false)}>
        <Spin spinning={loading.value}>
          <Form ref="formRef" labelCol={{ span: 4 }} model={formState} rules={rules}>
            {
              formItems.value.map((it) => {
                return (
                  <>
                    <div class="text-16px mb-15px">{it.formName}</div>
                    {
                      it.elements.map((ele: any) => (
                        <>
                          <FormItem label={ele.label} name={ele.key}>
                            {renderFormItems(ele)}
                          </FormItem>
                        </>
                      ))
                    }
                  </>
                )
              })
            }
            <FormItem wrapperCol={{ span: 18, offset: 4 }}>
              <Space class="w-full flex justify-end">
                <Button onClick={() => open.value = false}>
                  取消
                </Button>
                <Button loading={submitLoading.value} type="primary" onClick={onSubmit}>
                  提交
                </Button>
              </Space>
            </FormItem>
          </Form>
        </Spin>
      </Drawer>
    )
  },
})
